package com.lt.common;

import android.text.TextUtils;

import java.util.Random;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 随机数，随机字母。。。
 *
 * @author luotian
 */
public class RandomHelper {

    private static RandomHelper instance;
    public static final String NUMBERS_AND_LETTERS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    public static final String NUMBERS = "0123456789";
    public static final String LETTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    public static final String LETTERS_CAPITAL = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    public static final String LETTERS_LOWER_CASE = "abcdefghijklmnopqrstuvwxyz";

    private RandomHelper() {
    }

    public static RandomHelper getInstance() {
        if (instance == null) {
            synchronized (RandomHelper.class) {
                instance = new RandomHelper();
            }
        }
        return instance;
    }

    /**
     * 用于随机选的字符和数字
     */
    private static final String BASE_CHAR_NUMBER = LETTERS_LOWER_CASE + NUMBERS;


    /**
     * 获取随机数生成器对象<br>
     * ThreadLocalRandom是JDK 7之后提供并发产生随机数，能够解决多个线程发生的竞争争夺。
     *
     * @return {@link ThreadLocalRandom}
     * @since 3.1.2
     */
//    public static ThreadLocalRandom getRandom()
//    {
//        return ThreadLocalRandom.current();
//    }
    private static Random _random;

    public Random getRandom() {
        if (_random == null) {
            _random = new Random();
        }
        return _random;
    }

    /**
     * 从NUMBERS_AND_LETTERS中，获取特定长度的随机字符串
     *
     * @param length 长度
     */
    public String getRandomNumbersAndLetters(int length) {
        return getRandom(NUMBERS_AND_LETTERS, length);
    }

    /**
     * 从指定字符串中获取特定长度的随机字符串
     */
    public String getRandom(String source, int length) {
        return TextUtils.isEmpty(source) ? null : getRandom(
                source.toCharArray(), length);
    }

    /**
     * 从指定字符中获取特定长度的随机字符
     */
    public String getRandom(char[] sourceChar, int length) {
        if (sourceChar == null || sourceChar.length == 0 || length < 0) {
            return null;
        }

        StringBuilder str = new StringBuilder(length);
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            str.append(sourceChar[random.nextInt(sourceChar.length)]);
        }
        return str.toString();
    }

    public String getRandomNumbers(int length) {
        return getRandom(NUMBERS, length);
    }

    public String getRandomLetters(int length) {
        return getRandom(LETTERS, length);
    }

    public String getRandomCapitalLetters(int length) {
        return getRandom(LETTERS_CAPITAL, length);
    }

    public String getRandomLowerCaseLetters(int length) {
        return getRandom(LETTERS_LOWER_CASE, length);
    }

    public int getRandom(int max) {
        return getRandom(0, max);
    }

    public int getRandom(int min, int max) {
        if (min > max) {
            return 0;
        }
        if (min == max) {
            return min;
        }
        return min + new Random().nextInt(max - min);
    }

    /**
     * 随机bytes
     *
     * @param length 长度
     * @return bytes
     */
    public byte[] randomBytes(int length) {
        byte[] bytes = new byte[length];
//        getRandom().nextBytes(bytes);
        getRandom().nextBytes(bytes);
        return bytes;
    }

    /**
     * 获得一个随机的字符串
     *
     * @param baseString 随机字符选取的样本
     * @param length     字符串的长度
     * @return 随机字符串
     */
    public String randomString(String baseString, int length) {
        final StringBuilder sb = new StringBuilder();

        if (length < 1) {
            length = 1;
        }
        int baseLength = baseString.length();
        for (int i = 0; i < length; i++) {
            int number = getRandom().nextInt(baseLength);
            sb.append(baseString.charAt(number));
        }
        return sb.toString();
    }

    /**
     * 获得一个随机的字符串（只包含数字和字符）
     *
     * @param length 字符串的长度
     * @return 随机字符串
     */
    public String randomString(int length) {
        return randomString(BASE_CHAR_NUMBER, length);
    }

    /**
     * 洗牌？？？
     * <p>
     * Shuffling algorithm, Randomly permutes the specified array using a
     * default source of randomness
     *
     * @param objArray
     * @return
     */
    public boolean shuffle(Object[] objArray) {
        if (objArray == null) {
            return false;
        }

        return shuffle(objArray, getRandom(objArray.length));
    }

    /**
     * Shuffling algorithm, Randomly permutes the specified array
     *
     * @param objArray
     * @param shuffleCount
     * @return
     */
    public boolean shuffle(Object[] objArray, int shuffleCount) {
        int length;
        if (objArray == null || shuffleCount < 0
                || (length = objArray.length) < shuffleCount) {
            return false;
        }

        for (int i = 1; i <= shuffleCount; i++) {
            int random = getRandom(length - i);
            Object temp = objArray[length - i];
            objArray[length - i] = objArray[random];
            objArray[random] = temp;
        }
        return true;
    }

    /**
     * Shuffling algorithm, Randomly permutes the specified int array using a
     * default source of randomness
     *
     * @param intArray
     * @return
     */
    public int[] shuffle(int[] intArray) {
        if (intArray == null) {
            return null;
        }
        return shuffle(intArray, getRandom(intArray.length));
    }

    /**
     * Shuffling algorithm, Randomly permutes the specified int array
     *
     * @param intArray
     * @param shuffleCount
     * @return
     */
    public int[] shuffle(int[] intArray, int shuffleCount) {
        int length;
        if (intArray == null || shuffleCount < 0
                || (length = intArray.length) < shuffleCount) {
            return null;
        }

        int[] out = new int[shuffleCount];
        for (int i = 1; i <= shuffleCount; i++) {
            int random = getRandom(length - i);
            out[i - 1] = intArray[random];
            int temp = intArray[length - i];
            intArray[length - i] = intArray[random];
            intArray[random] = temp;
        }
        return out;
    }

    //

    /**
     * @return 随机UUID
     */
    public String randomUUID() {
        return UUID.randomUUID().toString();
    }

    /**
     * 简化的UUID，去掉了横线
     *
     * @return 简化的UUID，去掉了横线
     * @since 3.2.2
     */
    public String simpleUUID() {
        return randomUUID().replace("-", "");
    }
}
